package com.gitee.wsl.ext.number

import androidx.annotation.FloatRange
import kotlin.jvm.JvmName

/** Linearly interpolates between two values by a normalized value. This is the opposite of inverse_lerp. */
fun lerp(from: Int, to: Int, weight: Float) = from + weight * (to - from)

/** Linearly interpolates between two values by a normalized value. This is the opposite of inverse_lerp. */
fun lerp(from: Long, to: Long, weight: Double) = from + weight * (to - from)


// ---
/** Linearly interpolates between fromValue to toValue on progress position.  */
@JvmName("lerpFloat")
fun lerp(fromValue: Float, toValue: Float,@FloatRange(from = 0.0, to = 1.0) progress: Float): Float {
    return fromValue + (toValue - fromValue) * progress
}

@JvmName("lerpDouble")
fun lerp(fromValue: Double, toValue: Double, progress: Double): Double {
    return fromValue + (toValue - fromValue) * progress
}

/**
 * Linearly interpolate between two [Float]s when the [fraction] is in a given range.
 */
fun lerp(
    startValue: Float,
    endValue: Float,
    @FloatRange(from = 0.0, to = 1.0) startFraction: Float,
    @FloatRange(from = 0.0, to = 1.0) endFraction: Float,
    @FloatRange(from = 0.0, to = 1.0) fraction: Float
): Float {
    if (fraction < startFraction) return startValue
    if (fraction > endFraction) return endValue

    return lerp(startValue, endValue, (fraction - startFraction) / (endFraction - startFraction))
}

/**
 * Calculates a number between two numbers at a specific increment. The amt
 * parameter is the amount to interpolate between the two values where 0.0
 * equal to the first point, 0.1 is very near the first point, 0.5 is
 * half-way in between, and 1.0 is equal to the second point. If the
 * value of amt is more than 1.0 or less than 0.0, the number will be
 * calculated accordingly in the ratio of the two given numbers. The lerp
 * function is convenient for creating motion along a straight
 * path and for drawing dotted lines.
 *
 * @method lerp
 * @param start first value
 * @param stop second value
 * @param amt number
 * @return lerped value
 */
fun Float.lerp(start: Float, stop: Float): Float {
    return this * (stop - start) + start
}

/*
fun Int.lerp(start: Int, stop: Int): Int {
    return this * (stop - start) + start
}
*/

fun Double.lerp(start: Double, stop: Double): Double {
    return this * (stop - start) + start
}